package settingsapp.gestures;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.StreamCorruptedException;
import java.util.Vector;

import android.app.Activity;
import android.content.Context;
import android.util.Log;

public class GestureLibrary {

	public static final String TAG = GestureLibrary.class.getSimpleName();
	public final String libFileName = "gestures.glib";
	
	private Activity myActivity;
	Vector<TargetGesture> gestureVector;
	
	public GestureLibrary(Activity act)
	{
		myActivity = act;
		gestureVector = new Vector<TargetGesture>();	
		loadLibrary();
	}
	
	public TargetGesture identifyGesture(TargetGesture gesture)
	{
		for(int i=0; i<gestureVector.size(); i++)
		{
			if(gestureVector.elementAt(i).equals(gesture))
				return gestureVector.elementAt(i);
		}
		
		return null;
	}
	
	public TargetGesture identifyTerminatingGesture(TargetGesture gesture)
	{
		for(int i=0; i<gestureVector.size(); i++)
		{
			if(gestureVector.elementAt(i).equalsWithTerminating(gesture))
				return gestureVector.elementAt(i);				
		}
		
		return null;
	}
	
	private void loadLibrary()
	{
		int numGestures;
		FileInputStream fis = null;
		ObjectInputStream ois = null;		
		
		try {
			fis = myActivity.openFileInput(libFileName);
		} catch (FileNotFoundException e) {
			Log.w(TAG, "Gesture library file not found, attemping to create.");
			saveLibrary();	// Creates a new library with 0 stored gestures
			return;
		}
		
		try {

			ois = new ObjectInputStream(fis);
			
			// Read in the number of stored gestures			
			numGestures = ois.readInt();
			// Make sure the vector is empty and has enough room for the new gestures
			gestureVector.clear();
			gestureVector.ensureCapacity(numGestures);
			
			for(int i=0; i<numGestures; i++)
			{
				gestureVector.add((TargetGesture)ois.readObject());
			}			
			ois.close();
		} catch (StreamCorruptedException e) {
			Log.e(TAG, "Error reading gesture library: stream corruped."); 
			gestureVector.clear(); saveLibrary();
		} catch (IOException e) {
			Log.e(TAG, "Error reading gesture library.");
			gestureVector.clear(); saveLibrary();
		} catch (ClassNotFoundException e) {
			Log.e(TAG, "Error reading gesture library: invalid gesture format.");
			gestureVector.clear(); saveLibrary();
		}		
	}
	
	public boolean addGesture(TargetGesture gesture, boolean overwrite)
	{
		for(int i=0; i<gestureVector.size(); i++)
		{
			// Check to see if the gesture already exists
			if(gestureVector.elementAt(i).equals(gesture))
			{	
				if(overwrite)
					gestureVector.setElementAt(gesture, i);
				else
					return false;				
			}			
		}
		gestureVector.add(gesture);
		saveLibrary();
		return true;
	}
	
	public void deleteLibrary()
	{
		gestureVector.clear();		
	}
	
	public void saveLibrary()
	{
		FileOutputStream fos = null;
		ObjectOutputStream oos = null;		
		// Get the output stream
		try {
			fos = myActivity.openFileOutput(libFileName, Context.MODE_PRIVATE);
			
		} catch (FileNotFoundException e) {
			Log.e(TAG, "Error creating gesture library output file.");
			e.printStackTrace();
		}
		// Write out all of the gestures in the vector (saving them)
		try {
			// Get an object output stream
			oos = new ObjectOutputStream(fos);
			// Write the number of gestures to be saved
			oos.writeInt(gestureVector.size());
			for(int i=0; i<gestureVector.size(); i++)
			{
				oos.writeObject(gestureVector.elementAt(i));
			}
			oos.flush();
			oos.close();			
		} catch (IOException e) {
			Log.e(TAG, "Error writing gesture library to file.");
			e.printStackTrace();
		}		
	}	
}
